package com.uoko.common.io;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.*;

/**
 * <p>
 * IO流工具类
 * </p>
 *
 * @author xianguo
 * Email xianguo@uoko.com
 * created by 2018/6/6 0006
 */
public class IOUtil {
    private static final Logger logger = LoggerFactory.getLogger(IOUtil.class);

    public static String readDirOrFile(String filePath, String fileEncoding) {
        File f = new File(filePath);
        String temp = "";
        if (f.isDirectory()) {
            File[] files = f.listFiles();
            for (File temp_file : files) {
                temp += readDirOrFile(temp_file.getAbsolutePath(), fileEncoding);
            }
            return temp;
        }
        return readFile(filePath, fileEncoding);
    }

    /**
     * fileEncoding若为null,则采用系统默认编码 功能： 读取一个文件的文本内容
     *
     * @param filePath
     * @param fileEncoding
     * @return
     */
    public static String readFile(String filePath, String fileEncoding) {
        if (fileEncoding == null) {
            fileEncoding = System.getProperty("file.encoding");
        }
        File file = new File(filePath);
        BufferedReader br = null;

        String line = null;

        StringBuilder sb = new StringBuilder();

        try {
            br = new BufferedReader(new InputStreamReader(new FileInputStream(
                    file), fileEncoding));
            while ((line = br.readLine()) != null) {
                sb.append(line + "\n");
            }
            return sb.toString();
        } catch (Exception e) {
            logger.info(e.getLocalizedMessage());
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    logger.info(e.getLocalizedMessage());
                    logger.info("关闭IOUtil流时出现错误!");
                }
            }
        }
        return null;
    }

    // 将按行读出的字符串，统一加入到set中，直接去重
    public static Set<String> readFileToSet(String filePath, String fileEncoding) {
        if (fileEncoding == null) {
            fileEncoding = System.getProperty("file.encoding");
        }
        File file = new File(filePath);
        BufferedReader br = null;

        String line = null;

        Set<String> lineSet = new HashSet<String>();

        try {
            br = new BufferedReader(new InputStreamReader(new FileInputStream(
                    file), fileEncoding));
            while ((line = br.readLine()) != null) {
                line = line.trim();
                if (StringUtils.isNotBlank(line)
                        && (!line.startsWith("#"))) {
                    lineSet.add(line);
                }
            }
            return lineSet;
        } catch (Exception e) {
            logger.info(e.getLocalizedMessage());
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    logger.info(e.getLocalizedMessage());
                    logger.info("关闭IOUtil流时出现错误!");
                }
            }
        }
        return null;
    }

    // 按文件的开始行和结束行，部分读取文件的内容,以字符串返回
    public static String readFile(String filePath, String fileEncoding,
                                  long begin_line_number, long end_line_number) {
        if (fileEncoding == null) {
            fileEncoding = System.getProperty("file.encoding");
        }
        File file = new File(filePath);
        BufferedReader br = null;

        String line = null;

        StringBuilder sb = new StringBuilder();

        try {
            br = new BufferedReader(new InputStreamReader(new FileInputStream(
                    file), fileEncoding));
            int i = 0;
            // 空读完前边的行
            while (i < begin_line_number && (line = br.readLine()) != null) {
                i++;
            }

            while ((line = br.readLine()) != null
                    && begin_line_number < end_line_number) {
                sb.append(line + "\n");
                begin_line_number++;
            }
            // System.out.println("line---"+line);
            return sb.toString();
        } catch (Exception e) {
            logger.info(e.getLocalizedMessage());
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    logger.info(e.getLocalizedMessage());
                    logger.info("关闭IOUtil流时出现错误!");
                }
            }
        }
        return null;
    }

    // 按文件的开始行和结束行，部分读取文件的内容,以list集合返回
    public static List<String> readFileToList(String filePath,
                                              String fileEncoding, long begin_line_number, long end_line_number) {
        if (fileEncoding == null) {
            fileEncoding = System.getProperty("file.encoding");
        }
        File file = new File(filePath);
        BufferedReader br = null;

        String line = null;

        List<String> list = new ArrayList<String>();

        try {
            br = new BufferedReader(new InputStreamReader(new FileInputStream(
                    file), fileEncoding));
            int i = 0;
            // 空读完前边的行
            while (i < begin_line_number && (line = br.readLine()) != null) {
                i++;
            }

            while ((line = br.readLine()) != null
                    && begin_line_number < end_line_number) {
                list.add(line);
                begin_line_number++;
            }
        } catch (Exception e) {
            logger.info(e.getLocalizedMessage());
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    logger.info(e.getLocalizedMessage());
                    logger.info("关闭IOUtil流时出现错误!");
                }
            }
        }
        return list;
    }



    // 将对象写入到文件中

    /**
     * 以追加的方式向文件中写入
     *
     */

    // 将字符串转化成list集合存储，以\n作为行分隔符
    public static List<String> tranBatchLineToList(String source) {
        if (source == null || source.isEmpty()) {
            return null;
        }
        List<String> lineList = new LinkedList<String>();
        StringReader sb = new StringReader(source);
        BufferedReader br = new BufferedReader(sb);

        String temp_line = null;
        try {
            while ((temp_line = br.readLine()) != null) {
                lineList.add(temp_line);
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return lineList;
    }

    // 将文件读出,并以list对象来保存
    public static List<String> getLineArrayFromFile(String path, String encoding) {
        String keywordString = readDirOrFile(path, encoding);
        List<String> lineArray = new LinkedList<String>();

        try {
            String temp_line = null;
            StringReader sr = new StringReader(keywordString);
            BufferedReader br = new BufferedReader(sr);
            while ((temp_line = br.readLine()) != null) {
                if (!temp_line.startsWith("#")) {
                    lineArray.add(temp_line);
                }
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return lineArray;
    }

    // 得到某个文件的bufferedReader流
    public static BufferedReader getBufferedReader(String filePath,
                                                   String encoding) {
        BufferedReader br = null;
        try {
            FileInputStream fis = new FileInputStream(new File(filePath));
            br = new BufferedReader(new InputStreamReader(fis, encoding));
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return br;
    }

    // 得到一个文件的inputstream
    public static InputStream getInputStream(String filePath) {
        try {
            FileInputStream fis = new FileInputStream(new File(filePath));
            return fis;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // 得到一个字符串的BufferedReader对象
    public static BufferedReader getBufferedReader(String strValue) {
        BufferedReader br = null;
        try {
            StringReader sb = new StringReader(strValue);
            br = new BufferedReader(sb);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return br;
    }

    // 将inputstream转化为指定encoding的字符流
    public static BufferedReader convertInputStreamToBufferedReader(
            InputStream inStream, String encoding) {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(inStream, encoding));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return br;
    }

    // 关闭字符流
    public static void closeReader(Reader reader) {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 得到指定的文本的指定的行内容
     *
     * @param path
     * @param encoding
     * @param begin_line_number
     * @param line_length
     * @return
     */
    public static List<String> getLineArrayFromFile(String path,
                                                    String encoding, long begin_line_number, int line_length) {
        long end_line_number = begin_line_number + line_length;

        return readFileToList(path, encoding, begin_line_number,
                end_line_number);
    }

    public static List<String> tranBatchLineToList(String source,
                                                   int begin_line_number, int end_line_number) {
        if (source == null || source.isEmpty()) {
            return null;
        }
        List<String> lineList = new LinkedList<String>();
        StringReader sb = new StringReader(source);
        BufferedReader br = new BufferedReader(sb);

        String temp_line = null;
        try {
            int i = 0;
            // 空读完前边的行
            while (i < begin_line_number && (temp_line = br.readLine()) != null) {
                i++;
            }
            while ((temp_line = br.readLine()) != null
                    && begin_line_number < end_line_number) {
                lineList.add(temp_line);
                begin_line_number++;
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return lineList;
    }

    // 将list转换为string对象
    public static String tranListToString(List list) {
        if (list == null || list.isEmpty()) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for (Object line : list) {
            if (line.toString().trim().length() > 0) {
                sb.append(line);
            }
        }
        return sb.toString();
    }

    // 得到配置文件的bufferedreader流
    public static BufferedReader getTextBufferedReader4ConfigFile(
            String configFile, String encoding) {
        if (StringUtils.isBlank(configFile)) {
            return null;
        }
        InputStream is = sun.nio.ch.IOUtil.class.getClassLoader().getResourceAsStream(
                configFile);
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(is, encoding));
            return br;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    // 从配置文件中得到inputstream
    public static InputStream getInputStreamByConfigPath(String configPath) {
        InputStream is = sun.nio.ch.IOUtil.class.getClassLoader().getResourceAsStream(
                configPath);
        return is;
    }

    public static String toString(InputStream inputStream, String charset) throws IOException{
        BufferedReader bf=new BufferedReader(new InputStreamReader(inputStream,charset));
        StringBuffer buffer = new StringBuffer();
        String line="";
        while((line=bf.readLine())!=null){
            buffer.append(line);
        }
        return buffer.toString();
    }
}
